// #pragma once 

// template<class T>
// class SmartPtr
// {
//   public:
//     SmartPtr(T *ptr): _ptr(ptr)
//     {}
//     T& operator*()
//     {
//         return *_ptr;
//     }
//     T* operator->()
//     {
//         return _ptr;
//     }
//     ~SmartPtr()
//     {
//         delete _ptr;
//         cout << _ptr << endl;
//     }
//   private:
//     T *_ptr;
// };

// template<class T>
// class AutoPtr
// {
//   public:
//     AutoPtr(T *ptr)
//         : _ptr(ptr)
//     {}
//     AutoPtr(AutoPtr<T>& ap)
//         : _ptr(ap._ptr)
//     {
//         ap._ptr = nullptr;
//     }

//     T& operator*()
//     {
//         return *_ptr;
//     }
//     T* operator->()
//     {
//         return _ptr;
//     }
//     AutoPtr<T>& operator=(AutoPtr<T> &ap)
//     {
//         if(this != &ap)
//         {
//             delete _ptr;
//             _ptr = ap._ptr;
//             ap._ptr = nullptr;
//         }
//         return *this;
//     }
//     ~AutoPtr()
//     {
//         delete _ptr;
//         cout << _ptr << endl;
//     }
//   private:
//     T *_ptr;
// };

// template<class T>
// class UniquePtr
// {
//   public:
//     UniquePtr(T *ptr)
//         : _ptr(ptr)
//     {}
//     //设计思路：某些场景下智能指针仅管理资源，无需拷贝。
//     UniquePtr(const UniquePtr<T>& up) = delete;
//     UniquePtr<T>& operator=(UniquePtr<T> &up) = delete;

//     T& operator*()
//     {
//         return *_ptr;
//     }
//     T* operator->()
//     {
//         return _ptr;
//     }
    
//     ~UniquePtr()
//     {
//         delete _ptr;
//         cout << _ptr << endl;
//     }
//   private:
//     T *_ptr;
// };

// template<class T>
// class SharePtr
// {
//   public:
//     explicit SharePtr(T *ptr = nullptr)
//         : _ptr(ptr)
//         , _pCount(new int(1))
//         , _pMtx(new mutex) 
//     {}
//     void add_ref()
//     {
//         _pMtx->lock();
//         ++(*_pCount);
//         _pMtx->unlock();
//     }
//     void release_ref()
//     {
//         bool flag = false;
//         _pMtx->lock();
//         if(--(*_pCount) == 0 && _ptr)
//         {
//             delete _ptr;
//             delete _pCount;
//             flag = true;
//             cout << "release: " << _ptr << endl;
//         }
//         _pMtx->unlock();
//         if(flag == true)
//         {
//             delete _pMtx;
//         }
//     }
//     SharePtr(SharePtr<T>& sp)
//         : _ptr(sp._ptr)
//         , _pCount(sp._pCount)
//         , _pMtx(sp._pMtx)
//     {
//         add_ref();
//     }

//     T& operator*()
//     {
//         return *_ptr;
//     }
//     T* operator->()
//     {
//         return _ptr;
//     }
//     T* get()
//     {
//         return _ptr; 
//     }
//     int use_count()     //获取引用计数
//     {   
//         return *_pCount;
//     }
//     // SharePtr<T>& operator=(const SharePtr<T> &sp)
//     // {
//     //     if(this != &sp)
//     //     {
//     //         this->~SharePtr();
//     //         _ptr = sp._ptr;
//     //         _pCount = sp._pCount;
//     //         ++(*sp._pCount);
//     //     }
//     //     return *this;
//     // }
//     SharePtr<T>& operator=(SharePtr<T> sp)
//     {
//         swap(_ptr, sp._ptr);
//         swap(_pCount, sp._pCount);
//         return *this;
//     }
//     ~SharePtr()
//     {
//         release_ref();
//     }
//   private:
//     T *_ptr;
//     int *_pCount;
//     mutex *_pMtx;
// };

// template<class T>
// class WeakPtr
// {
//   public:
//     WeakPtr(): _ptr(nullptr)
//     {}
//     WeakPtr(SharePtr<T>& sp): _ptr(sp.get())
//     {}
//     WeakPtr(WeakPtr<T>& wp): _ptr(wp.get())
//     {}
//     WeakPtr<T>& operator=(SharePtr<T>& sp)
//     {
//         _ptr = sp.get();
//         return *this;
//     }
//     WeakPtr<T>& operator=(WeakPtr<T>& wp)
//     {
//         _ptr = wp.get();
//         return *this;
//     }
//     T& operator*()
//     {
//         return *_ptr;
//     }
//     T* operator->()
//     {
//         return _ptr;
//     }
//     T* get()
//     {
//         return _ptr;
//     }
//   private:
//     T *_ptr;
// };